package com.newlink.building.common_base.utils

import android.content.Context
import android.content.Intent
import android.net.ConnectivityManager
import android.net.Network
import android.net.NetworkCapabilities
import android.net.NetworkInfo
import android.net.wifi.WifiManager
import android.os.Build
import android.telephony.TelephonyManager
import android.util.Log
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import java.io.BufferedReader
import java.io.IOException
import java.io.InputStreamReader
import java.net.HttpURLConnection
import java.net.Inet4Address
import java.net.InetAddress
import java.net.NetworkInterface
import java.net.SocketException
import java.net.URL
import java.util.Enumeration


object NetWorkUtil {

    private const val TIMEOUT = 3000 // TIMEOUT

    /**
     * check NetworkAvailable
     *
     * @param context
     * @return
     */
    fun isNetworkAvailable(context: Context): Boolean {
        val manager =
            context.applicationContext.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
        val info = manager.activeNetworkInfo
        return !(null == info || !info.isAvailable)
    }

    /**
     * check NetworkConnected
     *
     * @param context
     * @return
     */
    fun isNetworkConnected(context: Context): Boolean {
        val manager =
            context.applicationContext.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
        val info = manager.activeNetworkInfo
        return !(null == info || !info.isConnected)
    }

    fun isNetworkConnected(context: Context, intent: Intent): Boolean {
        var conn =
            context.applicationContext.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
        var networkInfo: NetworkInfo? = conn.activeNetworkInfo
        var network: Network? = conn.activeNetwork
        if (networkInfo == null) {
            return false
        }

        val capabilities: NetworkCapabilities? = conn.getNetworkCapabilities(network)

        if (networkInfo?.type == ConnectivityManager.TYPE_MOBILE) {
            return capabilities?.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) == true
        }

        if (networkInfo?.type == ConnectivityManager.TYPE_WIFI) {
            return capabilities?.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) == true
        }

        val hasCapability =
            capabilities?.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) == true
        return hasCapability
    }

    /**
     * 得到ip地址
     *
     * @return
     */
    fun getLocalIpAddress(): String {
        var ret = ""
        try {
            val en = NetworkInterface.getNetworkInterfaces()
            while (en.hasMoreElements()) {
                val enumIpAddress = en.nextElement().inetAddresses
                while (enumIpAddress.hasMoreElements()) {
                    val netAddress = enumIpAddress.nextElement()
                    if (!netAddress.isLoopbackAddress) {
                        ret = netAddress.hostAddress.toString()
                    }
                }
            }
        } catch (ex: SocketException) {
            ex.printStackTrace()
        }
        return ret
    }

    //获取ip地址
    fun getLocalIPAddress(context: Context): String? {
        val info =
            (context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager).activeNetworkInfo
        if (info != null && info.isConnected) {
            if (info.type == ConnectivityManager.TYPE_MOBILE) {    //3G/4G网络
                try {
                    val en: Enumeration<NetworkInterface> = NetworkInterface.getNetworkInterfaces()
                    while (en.hasMoreElements()) {
                        val intf: NetworkInterface = en.nextElement()
                        val enumIpAddr: Enumeration<InetAddress> = intf.inetAddresses
                        while (enumIpAddr.hasMoreElements()) {
                            val inetAddress: InetAddress = enumIpAddr.nextElement()
                            if (!inetAddress.isLoopbackAddress && inetAddress is Inet4Address) {
                                return inetAddress.getHostAddress()
                            }
                        }
                    }
                } catch (e: SocketException) {
                    return null
                }
            } else if (info.type == ConnectivityManager.TYPE_WIFI) {     // wifi
                val wifiManager =
                    context.getSystemService(Context.WIFI_SERVICE) as WifiManager
                val wifiInfo = wifiManager.connectionInfo
                return int2Sip(wifiInfo.ipAddress)
            } else if (info.type == ConnectivityManager.TYPE_ETHERNET) {    //有线
                val mConnectivityManager =
                    context.applicationContext.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
                var network: Network? = null
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                    network = mConnectivityManager.activeNetwork
                    val linkProperties = mConnectivityManager.getLinkProperties(network)
                    for (linkAddress in linkProperties!!.linkAddresses) {
                        val address = linkAddress.address
                        if (address is Inet4Address) {
                            return address.getHostAddress()
                        }
                    }
                }
                return "0.0.0.0"
            }
        } else {
            return "0.0.0.0"
        }
        return null
    }

    /**
     * 将ip的整数形式转换成ip形式
     * @param ip
     * @return
     */
    fun int2Sip(ip: Int): String {
        val sb = StringBuilder()
        sb.append(ip and 0xFF).append(".")
        sb.append(ip shr 8 and 0xFF).append(".")
        sb.append(ip shr 16 and 0xFF).append(".")
        sb.append(ip shr 24 and 0xFF)
        return sb.toString()
    }

    /**
     * ping "http://www.baidu.com"
     *
     * @return
     */
    private fun pingNetWork(): Boolean {
        var result = false
        var httpUrl: HttpURLConnection? = null
        try {
            httpUrl = URL("http://www.baidu.com").openConnection() as HttpURLConnection
            httpUrl.connectTimeout = TIMEOUT
            httpUrl.connect()
            result = true
        } catch (e: IOException) {
        } finally {
            if (null != httpUrl) {
                httpUrl.disconnect()
            }
        }
        return result
    }

    /**
     * check is3G
     *
     * @param context
     * @return boolean
     */
    @JvmStatic
    fun is3G(context: Context): Boolean {
        val connectivityManager =
            context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
        val activeNetInfo = connectivityManager.activeNetworkInfo
        return activeNetInfo != null && activeNetInfo.type == ConnectivityManager.TYPE_MOBILE
    }

    /**
     * isWifi
     *
     * @param context
     * @return boolean
     */
    @JvmStatic
    fun isWifi(context: Context): Boolean {
        val connectivityManager =
            context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
        val activeNetInfo = connectivityManager.activeNetworkInfo
        return activeNetInfo != null && activeNetInfo.type == ConnectivityManager.TYPE_WIFI
    }

    /**
     * is2G
     *
     * @param context
     * @return boolean
     */
    @JvmStatic
    fun is2G(context: Context): Boolean {
        val connectivityManager =
            context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
        val activeNetInfo = connectivityManager.activeNetworkInfo
        return activeNetInfo != null &&
                (
                        activeNetInfo.subtype == TelephonyManager.NETWORK_TYPE_EDGE ||
                                activeNetInfo.subtype == TelephonyManager.NETWORK_TYPE_GPRS ||
                                activeNetInfo.subtype == TelephonyManager.NETWORK_TYPE_CDMA
                        )
    }

    /**
     * is wifi on
     */
    fun isWifiEnabled(context: Context): Boolean {
        val wifiManager = context.getSystemService(Context.WIFI_SERVICE) as WifiManager
        return wifiManager.isWifiEnabled
    }

    /**
     * 判断MOBILE网络是否可用
     */
    fun isMobile(context: Context?): Boolean {
        if (context != null) {
            // 获取手机所有连接管理对象(包括对wi-fi,net等连接的管理)
            val manager =
                context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
            // 获取NetworkInfo对象
            val networkInfo = manager.activeNetworkInfo
            // 判断NetworkInfo对象是否为空 并且类型是否为MOBILE
            if (networkInfo != null && networkInfo.type == ConnectivityManager.TYPE_MOBILE)
                return networkInfo.isAvailable
        }
        return false
    }

    fun ping(address: String) {
        val ipAddress = removeProtocolFromUrl(address)
        GlobalScope.launch {
            Log.i("NetWorkUtil", "ipAddress $ipAddress")
            val runtime = Runtime.getRuntime()
            try {
                val process = runtime.exec("/system/bin/ping -c 5 $ipAddress")
                val bufferedReader = BufferedReader(InputStreamReader(process.inputStream))
                var line: String?
                while ((bufferedReader.readLine().also { line = it }) != null) {
                    Log.d("NetWorkUtil", line!!)
                }
                process.waitFor()
            } catch (e: IOException) {
                Log.e("NetWorkUtil", "Error pinging $ipAddress", e)
            } catch (e: InterruptedException) {
                Log.e("NetWorkUtil", "Error pinging $ipAddress", e)
            }
        }
    }

    fun removeProtocolFromUrl(url: String): String {
        return url.replace("http://", "").replace("https://", "")
    }
}
